package com.stb.shared.util;
import java.util.HashMap;
import java.util.Map;

/**
 * @param <K> key type
 * @param <V> value type
 */
public class ThreadLocalMap<K, V> {
	
	private static final ThreadLocal<Map<?, ?>> maps = new ThreadLocal<Map<?, ?>>();
	
	/**
	 * Call back used to create map entries if they don't exist
	 * @param <K>
	 * @param <V>
	 */
	public interface CreateCallback<K, V> {
		public V create(K key);
	}

	/**
	 * Gets the entry for the specified key for the current thread instance of the map.
	 * If the entry is null, we call the callback to get the entry for the specified
	 * key and add it to the map.
	 *  
	 * @param key
	 * @param callback
	 * @return thread specific entry
	 */
	@SuppressWarnings("unchecked")
	public V get(K key, CreateCallback<K, V> callback) {
    	Map<K, V> map = (Map<K, V>) maps.get();
    	if (map == null) {
    		map = new HashMap<K, V>();
    		maps.set(map);
    	}

    	V value = map.get(key);
    	if (value == null) {
    		value = callback.create(key);
    		map.put(key, value);
    	}
    	return value;
	}
}
